﻿using System;
using System.Collections.Generic;
using System.Linq;
using personalplaner.business.common;
using personalplaner.business.dienstplan.plancollection;
using personalplaner.business.stamm;
using personalplaner.core.sql;

namespace personalplaner.dataprovider.services
{
	public partial class DiensteDataService
	{
		#region Get Methods

		/// <summary>
		/// Creates a List with the Dienstschema of a abteilung, [dienstid,gerechnet,einsatzprotag,dienstname,kurztext,langtext,abteilungid,abteilungname]
		/// </summary>
		/// <param name="settings"></param>
		/// <param name="schemaid">schemaid</param>
		/// <param name="abteilungid">abteilungid</param>
		/// <returns>[dienstid,gerechnet,einsatzprotag,dienstname,kurztext,langtext,abteilungid,abteilungname]</returns>
		public IEnumerable<Dienst> GetDiensteInSchema(DatabaseSettings settings, int schemaid, int abteilungid)
		{
			var stp = new Querry(settings, "get_dienstschema");

			stp.AddParameter("@schemaid", schemaid);
			stp.AddParameter("@abteilungid", abteilungid);

			var table = stp.ExecuteForDataTable();

			if (table.Rows.Count == 0)
				return null;

			try
			{
				return m_diensteData(table);
			}
			catch (Exception e)
			{
				throw new Exception("GetDiensteInSchema caused an error", e);
			}
		}

		/// <summary>
		/// [dienstid,gerechnet,einsatzprotag,dienstname,kurztext,langtext,abteilungid,abteilungname]
		/// </summary>
		/// <param name="settings"></param>
		/// <param name="schemaid">schemaid</param>
		/// <param name="abteilungid">abteilungid</param>
		/// <returns>[dienstid,gerechnet,einsatzprotag,dienstname,kurztext,langtext,abteilungid,abteilungname]</returns>
		public IEnumerable<Dienst> GetDienstNotInSchema(DatabaseSettings settings, int schemaid, int abteilungid)
		{

			var stp = new Querry(settings, "get_dienstnotinschema");
			stp.AddParameter("@schemaid", schemaid);
			stp.AddParameter("@abteilungid", abteilungid);

			var table = stp.ExecuteForDataTable();

			if (table.Rows.Count == 0)
				return null;

			try
			{
				return m_diensteData(table);
			}
			catch (Exception e)
			{
				throw new Exception("GetDienstNotInSchema caused an error", e);
			}
		}

		/// <summary>
		/// Gets a list of all dienste [DienstID,Name,Gerechnet,Typ,RGB,GanzerTag,Kurztext,Langtext]
		/// </summary>
		/// <param name="settings"></param>
		/// <param name="all">false = only active</param>
		/// <param name="addEmptyRow">add empty row at top</param>
		/// <returns>[DienstID,Name,Gerechnet,Typ,RGB,GanzerTag,Kurztext,Langtext]</returns>
		public IEnumerable<Dienst> GetDienste(DatabaseSettings settings, bool all, bool addEmptyRow)
		{
			string str = "select dienstid = DienstID, dienstname = Name, gerechnet = Gerechnet, typ = Typ, rgb = RGB, color = ColorName, ganzertag = GanzerTag, kurztext = Kurztext, langtext = Langtext from Dienst, Beschreibung b where Status = 0 and Dienst.BeschrID = b.BeschrID order by DienstID";
			if (all)
				str = "select dienstid = DienstID, dienstname = Name, gerechnet = Gerechnet, typ = Typ, rgb = RGB, color = ColorName, ganzertag = GanzerTag, kurztext = Kurztext, langtext = Langtext from Dienst, Beschreibung b where Dienst.BeschrID = b.BeschrID order by DienstID";

			var table = SimpleQuerry.ExecuteForDataTable(settings, str);

			if (table.Rows.Count == 0)
				return null;

			try
			{
				var lst = new List<Dienst>(m_diensteData(table));

				if (addEmptyRow)
				{
					lst.Insert(0, new Dienst());
				}

				return lst;
			}
			catch (Exception e)
			{
				throw new Exception("GetDienste caused an error", e);
			}
		}

        /// <summary>
        /// [dienstzeitid,dienstid,von,bis,typ,datumvon,datumbis,abteilungszeit]
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="dienstid">dienstid</param>
        /// <returns>[dienstzeitid,dienstid,von,bis,typ]</returns>
        public IEnumerable<DienstZeitCollection> GetDienstZeiten(DatabaseSettings settings, int dienstid)
        {
            var qu = new Querry(settings,"get_dienstzeiten");
            qu.AddParameter("@dienstid", dienstid);
            var table = qu.ExecuteForDataTable();

            if (table.Rows.Count == 0)
                return null;

            try
            {
                var lst = m_dienstZeitData(table).ToList();

                var col = new List<DienstZeitCollection>();

                while (lst.Count > 0)
                {
                    var von = lst[0].DatumVon;
                    var bis = lst[0].DatumBis;

                    var tmp = (from a in lst where a.DatumVon == von && a.DatumBis == bis select a).ToList();
                    var c = new DienstZeitCollection();

                    foreach (var a in tmp)
                    {
                        c.Add(a);
                        lst.Remove(a);
                    }

                    col.Add(c);
                }

                return (from a in col orderby a.DatumBis descending select a).ToList();
            }
            catch (Exception e)
            {
                throw new Exception("GetDienste caused an error", e);
            }
        }

		/// <summary>
		/// Creates a list with the Dienstschema of all abteilungen, [dienstid,gerechnet,einsatzprotag,dienstname,kurztext,langtext,abteilungid,abteilungname]
		///		- public static DataView GetDienstSchema(int schemaid, string mandid)
		/// </summary>
		/// <param name="settings"></param>
		/// <param name="schemaid">schemaid</param>
		/// <returns>[dienstid,gerechnet,einsatzprotag,dienstname,kurztext,langtext,abteilungid,abteilungname]</returns>
		public IEnumerable<DienstOverviewRow> GetPlanDienstOverview(DatabaseSettings settings, int schemaid)
		{
			return GetPlanDienstOverview(settings, schemaid, 0);
		}

		/// <summary>
		/// Creates a list with the Dienstschema of a abteilung, [dienstid,gerechnet,einsatzprotag,dienstname,kurztext,langtext,abteilungid,abteilungname]
		///		- public static DataView GetDienstSchema(int schemaid, int abteilungid, string mandid)
		/// </summary>
		/// <param name="settings"></param>
		/// <param name="schemaid">schemaid</param>
		/// <param name="abteilungid">abteilungid</param>
		/// <returns>[dienstid,gerechnet,einsatzprotag,dienstname,kurztext,langtext,abteilungid,abteilungname]</returns>
		public IEnumerable<DienstOverviewRow> GetPlanDienstOverview(DatabaseSettings settings, int schemaid, int abteilungid)
		{
			var stp = new Querry(settings, "get_dienstschema");

			stp.AddParameter("@schemaid", schemaid);
			stp.AddParameter("@abteilungid", abteilungid);

			var table = stp.ExecuteForDataTable();

			try
			{
				return m_PlanDienstOverviewData(table);
			}
			catch (Exception e)
			{
				throw new Exception("GetPlanDienstOverview caused an error", e);
			}
		}

		#endregion 

		#region Set Methods
		
		public bool SaveDiensteToSchema(DatabaseSettings settings, IEnumerable<Dienst> dienste, int schemaid, int abteilungid)
		{
			if (!SimpleQuerry.Execute(settings,
									  string.Format("delete from DienstSchema where SchemaID = {0} and AbteilungID = {1}", schemaid,
													abteilungid)))
			{
				return false;
			}

			foreach (var dienst in dienste)
			{
				if (!SimpleQuerry.Execute(settings,
											string.Format(
												"insert into DienstSchema (SchemaID,AbteilungID,DienstID,EinsatzProTag,Gerechnet) values ( {0}, {1}, {2}, {3}, 0)",
												schemaid,
												abteilungid,
												dienst.DienstID,
												dienst.EinsatzProTag)))
				{
					return false;
				}
			}

			return true;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="settings"></param>
		/// <param name="dienst"></param>
		/// <param name="mandantid"></param>
		/// <returns>the dienstid of the saved dienst</returns>
		public int SaveDienst(DatabaseSettings settings, Dienst dienst, string mandantid)
		{
			var stp = new Querry(settings, "set_neudienst");

			stp.AddParameter("@mandid", mandantid);
			stp.AddParameter("@dienstname", dienst.Name);
			stp.AddParameter("@kurztext", dienst.KurzText);
			stp.AddParameter("@beschreibung", dienst.LangText);
			stp.AddParameter("@gerechnet", dienst.IsGerechnet ? 1 : 0);
			stp.AddParameter("@RGB", 0);
			stp.AddParameter("@ColorName", dienst.ColorString);
			stp.AddParameter("@typ", dienst.Typ);
			stp.AddParameter("@GanzerTag", dienst.IsGanzerTag ? 1 : 0);
			var prm = stp.AddParameter("@dienstid", 0, System.Data.ParameterDirection.Output);

			if (stp.Execute(true))
				return (int)prm.Value;

			return 0;
		}

		//public void SetDienstZeit(int dienstid, string zeitVon, string zeitBis, string zeitEinheit, string datevon, string datebis, bool abteilungszeit)
		public bool SetDienstZeit(DatabaseSettings settings, DienstZeit dienstzeit)
		{
			var stp = new Querry(settings, "set_zeit");

			stp.AddParameter("@prsid", dienstzeit.DienstId);
			stp.AddParameter("@von", dienstzeit.Von);
			stp.AddParameter("@bis", dienstzeit.Bis);
			stp.AddParameter("@zeiteinheit", dienstzeit.ZeitEinheitTyp == business.enums.enZeiteinheit.Arbeit ? "Z" :  "P");
			stp.AddParameter("@datevon", dienstzeit.DatumVon);
			stp.AddParameter("@datebis", dienstzeit.DatumBis);
			stp.AddParameter("@abteilungszeit", dienstzeit.IsAbteilungsZeit ? 1 : 0);

			return stp.Execute();
		}

		#endregion

		#region Update Methods

		public bool UpdateDienst(DatabaseSettings settings, Dienst dienst)
		/* int dienstid, string name, string kurztext, string beschreibung, int gerechnet, int rgb, int diensttyp, int ganzertag)*/
		{
			var stp = new Querry(settings, "upd_dienst");

			stp.AddParameter("@dienstid", dienst.DienstID);
			stp.AddParameter("@dienstname", dienst.Name);
			stp.AddParameter("@kurztext", dienst.KurzText);
			stp.AddParameter("@beschreibung", dienst.LangText);
			stp.AddParameter("@gerechnet", dienst.IsGerechnet ? 1 : 0);
			stp.AddParameter("@RGB", 0);
			stp.AddParameter("@ColorName", dienst.ColorString);
			stp.AddParameter("@typ", dienst.Typ);
			stp.AddParameter("@GanzerTag", dienst.IsGanzerTag ? 1 : 0);

			return stp.Execute(true);
		}

		public bool DeleteDienst(DatabaseSettings settings, int dienstid)
		{
			var stp = new Querry(settings, "del_dienst");

			stp.AddParameter("@dienstid", dienstid);

			return stp.Execute();
		}

		public bool EndDienstZeiten(DatabaseSettings settings, int dienstid, DateTime enddate)
		{
			var str = string.Format("delete from DienstZeit where DienstID = {0} and datvon >= '{1}'", dienstid, enddate.ToString("yyyyMMdd"));
			var ok = SimpleQuerry.Execute(settings, str);

			if (ok)
			{
				str = string.Format("update DienstZeit set datbis = '{1}' where DienstID = {0} and datbis >= '{1}'", dienstid,
				                    enddate.ToString("yyyyMMdd"));
				ok = SimpleQuerry.Execute(settings, str);
			}

			return ok;
		}

		#endregion

		#region Delete Methods

		public bool DeleteDienstZeit(DatabaseSettings settings, int dienstid, DienstZeitCollection dienstzeit)
		{
			var str = string.Format("delete from DienstZeit where DienstID = {0} and datvon = '{1}' and datbis = '{2}'", dienstid, dienstzeit.DatumVon.ToString("yyyyMMdd"), dienstzeit.DatumBis.ToString("yyyyMMdd"));
			return SimpleQuerry.Execute(settings, str);
		}

		#endregion
	}
}
